<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Curl;
use Illuminate\Support\Facades\DB;
use Mockery\CountValidator\Exception;

trait Common
{
    public function getView($data, $msg = '', $code = 0, $ms = '') {
        $arr['data'] = $data;
        $msgCode = explode('_', $msg);
        $code = $code ? $code : $msgCode[0];
        $msgs = $ms ? $ms : $msgCode[1];
        $arr['code'] =$code;
        $arr['msg'] = $msgs;
        return response()->json($arr);
    }

    //统一请求方法
    public function remoteQuery($url,$value=[])
    {
        $value ['timestamp'] = time();
        $params = [
            'url' => config('web.api.url') . $url,
            'isPost' => true,  //post方式
            'dataStr' => [ //参数
                'sign' => $this->makeSign($value),
                'timestamp' => time(),
            ]
        ];

        foreach ($value as $filed => $item) {
            $params['dataStr'][$filed] = $item;
        }

        return $this->parse(Curl::query($params));
    }

    /**
     * 生成签名
     * @param array $not_sign_param     不参与加密的参数名
     * @return string                   签名，本函数不覆盖sign成员变量
     */
    public function makeSign($params,$not_sign_param = array())
    {
        // 签名步骤一：按字典序排序参数(对关联数组按照键名进行升序排序)
        ksort($params);
        $string = $this->toUrlParams($params,$not_sign_param);
        // 签名步骤二：在string后加入KEY
        $string = $string . "appkey" . config('web.api.key');
        // 签名步骤三：MD5加密
        $string = md5($string);
        // 签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }

    /**
     * 格式化参数格式化成url参数
     * @param array $not_sign_param     不参与加密的参数名
     * @return string                   返回拼接后的参数
     */
    public function toUrlParams($params,$not_sign_param = array())
    {
        $buff = "";
        foreach ($params as $k => $v) {
            if (!in_array('sign', $not_sign_param)) {
                array_push($not_sign_param, 'sign');
            }
            if (!in_array($k, $not_sign_param) && $v != "" && !is_array($v)) {
                $buff .= $k . $v;
            }
        }
        return $buff;
    }

    private function parse($data)
    {
        $data = json_decode($data,true);
        if (is_array($data)){
            if ($data['flag'] == 'false'){
                return $data['info'];
            } else {
                return $data['data']['obj'];
            }
        } else {
            return false;
        }
    }

    public function json_echo($flag, $data = array(), $info = '', $echo_type = 0, $count = 0, $error_code = 0)
    {
        $data = $this->unsetNull($data);//把 null转换为空'' 递归方式
        $result = $this->status_header($flag, $data, $info, $echo_type, $count);
        //header('Content-Type:application/json; charset=utf-8');
        return $result;
    }

    public function unsetNull($arr) {
        # 要过滤的参数
        $filter_param = array('relation_param');
        if ($arr !== null){
            if(is_array($arr)){
                if(!empty($arr)){
                    foreach($arr as $key => $value) {

                        if($value === null) {
                            if (in_array($key, $filter_param)) {
                                continue;
                            }
                            $arr[$key] = '';
                        } else {
                            $arr[$key] = $this->unsetNull($value);      //递归再去执行
                        }
                    }
                } else { // 数组不转为空
                    //$arr = '';
                }
            } else {
                //注意三个等号
                if($arr === null){
                    $arr = '';
                }
            }
        } else {
            $arr = '';
        }
        return $arr;
    }

     /**
     * API返回状态判断函数
     * @param $flag          标识
     * @param array $data    数据
     * @param string $info   提示
     * @param int $echo_type 返回类型（0表示非列表将data赋值给obj，1表示列表将data赋值给list）
     * @param int $count     总数(非当页条数，有翻页时)
     * @return mixed
     */
    public function status_header($flag, $data = array(), $info = "", $echo_type = 0, $count = 0) {

        switch ($flag) {
            case '#success':
                $status['flag'] = "success";
                $status['info'] = $info;
                break;
            case '#false':
                $status['flag'] = "false";
                $status['info'] = $info;
                break;
//        case '#upload'://上传状态
//            $status['flag'] = "success";
//            $status['info'] = $info;
//            break;
//        case '#address':
//            $status['flag'] = "address";
//            $status['info'] = $info;
//            break;
            case '#login':
                $status['flag'] = "login";
                $status['info'] = $info;
                break;
            case '#sys':
                $status['flag'] = "system";
                $status['info'] = "系统错误";
                break;
            case '#version':
                $status['flag'] = "version";
                $status['info'] = "您的版本过低，请升级"; //"您的版本过低，请升级";
                // 将下载相关信息写到data里面输出
                break;
            case '#newversion':
                $status['flag'] = "newversion";
                $status['info'] = "有新版本，请升级"; //"有新版本，请升级";
                // 将下载相关信息写到data里面输出
                break;
            default:
                $status['flag'] = $flag;
                $status['info'] = $info;
                break;
        }


        if (!$status['info'] && $flag == '#success') {
            $status['info'] = "操作成功";
        }

        $status['data']['obj'] = (object)array();
        $status['data']['list'] = array();
        $status['data']['count'] = 0;

        if (!empty($data)) {

            if ($echo_type == 0) {
                $status['data']['obj'] = $data;
                $status['data']['list'] = array();
                $status['data']['count'] = 0;
            }
            else {
                $count = ($count == 0) ? count($data) : $count;
                $status['data']['obj'] = (object)array();
                $status['data']['list'] = $data;
                $status['data']['count'] = $count;
            }
        }

        $status['time'] = time();
        return $status;
    }

    /**
     * 密码加密
     * @param $str
     * @param int $offSet
     * @return string
     */
    public function multiMD5($str, $offSet = 20) {
        $md5_str = md5($str);
        $length = $offSet > 30 ? 30 : $offSet;
        $md5_str = strtoupper($md5_str);
        $sub_str = substr($md5_str, $length);
        return strtoupper(md5($md5_str . $sub_str));
    }

    /**
     * 发送验证码
     * @param $phone
     * @param $phone
     * @param $type    发送类型 （1:注册 0:找回密码, 2:邀请好友 3：sdk财务, 4：后台登录验证 5:手机快速注册登录）
     */
    public function mobile_captch_set($request, $type) {
        $phone = $request->input('phone');
        $ip = $request->getClientIp();
        $where = [];
        $where[] = ['phone', ];
        $where[] = ['type', $type];

        $codes = DB::table('code')->where($where)->orderByDesc('create_time')->first();

        if ($codes && (time() - $codes->create_time < 90)) {
            $data['status'] = 0;
            $data['msg'] = '不能频繁发送!';
            return $data;
        }

        $captcha = rand(500000, 999999);
        $strContent = "验证码:" . $captcha . "如非本人操作,切勿将验证码告知他人,并请立即修改账号密码!【指娱游戏】";

        $strSmsParam = "userCode=" . env('SMS_USERCODE') . "&userPass=" . env('SMS_USERPASS') . "&DesNo=" . $phone . "&Msg=" . $strContent . "&Channel=0";
        $result_str = $this->postSend(env('SMS_URL'), $strSmsParam);

        $xmlResult = simplexml_load_string($result_str);
        $res = (int) $xmlResult;

        if ($res > 0) {
            //添加新记录
            $add = array();
            $add['code'] = $captcha;
            $add['ip'] = $ip;
            $add['type'] = $type;
            $add['phone'] = $phone;
            $add['create_time'] = time();
            //$flag = M('code')->add($add);
            $flag = DB::table('code')->insert($add);

            if ($flag) {
                $data['status'] = 1;
                $data['msg'] = '发送成功!';
            } else {
                $data['status'] = 0;
                $data['msg'] = '发送失败!';
            }
        } else {
            $data['status'] = 0;
            $data['msg'] = '发送失败!';
        }

        return $data;
    }

    /**
     * 验证手机验码
     * @param 用户名        $phone
     * @param 手机验证码     $mobile_captch
     * @param 验证类型       $used 0:验证码未使用掉 1:验证码使用掉
     * @param 发送类型       $send_type 1:注册 0:找回密码, 2:邀请好友 3：sdk财务, 4：后台登录验证 5:手机快速注册登录 6：绑定手机验证
     *                      7：更换手机验证
     * @return array()
     * @author dw
     */
    public function mobile_captch_get($phone, $captch, $used = 0, $send_type = -1) {

        $where = [];
        $where[] = ['phone', $phone];
        $where[] = ['type', $captch];
        if ($send_type != -1) {
            $where[] = ['send_type', $send_type];
        }

        $codes = DB::table('code')->where($where)->first();

        if ($codes) {
            if ($codes->create_time < time() - 60 * 5 && $codes->status == 0) {
                $data['status'] = 10;
                $data['msg'] = '验证码已超时，请重新获取';
                return $data;
            }

            if ($codes->status == 1) {
                $data['status'] = 0;
                $data['msg'] = '验证码已失效!';
                return $data;
            }

            if ($used) {
                $data['status'] = 1; //验证码未使用过 0:待验证 1:使用过  2:待二次验证
            } else {
                $data['status'] = 2;
            }

            if ($codes->code != $captch) {
                $data['status'] = 0;
                $data['msg'] = '输入的验证码不正确!';
                return $data;
            }

            //M('code')->where($where)->save(array('status' => $data['status']));
            DB::table('code')->where($where)->update('status', $data['status']);
            $data['msg'] = '验证成功!';
        } else {
            $data['status'] = 0;
            $data['msg'] = '验证失败!';
        }

        return $data;
    }

    public function postSend($url, $param) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }


}
